package impl;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;


public class Server {
	private HashMap<Socket, DataOutputStream> outputStreams = new HashMap<Socket, DataOutputStream>();
	private double dropProb = .1;
	private double delayProb = .1;
	private double dupProb = .1;
	
	public void run() throws IOException {
		int port = 14000;
		listen(port);
	}

	private void listen(int port) throws IOException {
		ServerSocket serverSocket = new ServerSocket(port);

		System.out
				.println("Chat Server is listening on socket " + serverSocket);

		// this will loop forever until the server is shut down
		while (true) {
			Socket socket = serverSocket.accept();

			System.out.println("Connection made to the server from socket "
					+ socket);

			// This will create the data stream to output input to the server
			// back to the clients
			DataOutputStream output = new DataOutputStream(
					socket.getOutputStream());

			outputStreams.put(socket, output);
			
			new ServerThread(this, socket);
		}
	}

	public void sendToReceiver(String message, Socket socket) {
		try {
			// Loop through available output streams(clients) and send message
			Collection<DataOutputStream> streams = outputStreams.values();
			
			double probability = 0.0;
			for (DataOutputStream stream : streams) {
				probability = Math.random();
				//drop message
				if(probability < dropProb){
					System.out.println("Server dropped packet.");
					break;
				}
				// send duplicate message
				probability = Math.random();
				if(probability < dupProb){
					System.out.println("Duplicate packet sent.");
					stream.writeUTF(message);
				}
				//delay message
				probability = Math.random();
				if(probability < delayProb){
					System.out.println("System delayed sending packet.");
					synchronized(this){
						wait(200);
					}
				}
				stream.writeUTF(message);
			}
		} catch (IOException e) {
			System.out.println(e.getMessage());
		} catch(InterruptedException e){
			System.out.println(e.getMessage());
		}
	}

	public void removeConnection(Socket socket) {
		outputStreams.remove(socket);
	}
}
